\ One way to test our FP ops is to do a number of calculations with with a known result at the end. The calculations should be simple enough that if we get the wrong answer, we've got a fighting chance of finding where things went wrong. So here we check that sin**2 (x) + cos**2 (x) = 1. We square the sine and cos in two different ways and use different operand modes, in the hope that any bugs in the operand accessing will show themselves. Also extra dummy local variables can be added or removed, to test correct use of the ExtraLocals area versus the D regs and FP regs.
: Q { %angle \ %temp1 %temp2 %temp3 %temp4 -- b }
db %angle sin -> %temp1
%angle cos -> %temp2
%temp1 %temp1 f* -> %temp3
%temp2 fdup f* -> %temp4
%temp3 %temp4 f+
1.0 f-
0.000000001 f< if true else false then ;
: TEST1
0.2 q . room: fltmem . ; \ Should print -1 100
endload
\ Here's a timing test:
: TEST2 { \ %a %b %c %d -- }
global ticks @
100. -> %a 200. -> %b 300. -> %c 400. -> %d
100000 0 DO
%a %b f* %c %d f* f+
%a %d f+ f/ -> fv
LOOP
global ticks @ - negate . cr fv e.
3 beep ;
\ This takes 60 secs. on a IIsi (20 MHz 68030) without FPU. With FPU, but still using SANE: 45 secs. (SANE has a lot of overhead.) With normal run-time FPU detection from Mops: 14.9 secs. With compiled (optimized) FPU code in Mops: 3.1 secs. The hand-coded assembly equivalent takes 1.5 secs.